using System;
using System.Collections.Generic;
using System.Linq;
using Arcane.Source.Client;
using Arcane.Source.Combat.Items;
using Arcane.Source.Combat.UltraSpells;
using Arcane.Source.Utils;
using Godot;

namespace Arcane.Source.Combat
{
    public class CombatContext : ViewContext<CombatView>
    {
        public event Action<CombatEndStats> OnCombatEnd;

        public override string ViewName => "combat";

        public PlayerEntity player;
        public Entity enemy;

        private bool _isEnd = false;
        private bool _pause = false;

        private Control _pauseDialog;

        private int[] eleminates = new int[Element.Size.AsInt()];

        public override void OnLoad(Msg msg)
        {
            var p = new PlayerEntity(1000, new Punch(100, 50), msg.Get<StringName[]>("runes"));
            var m = new SimpleEntity(1000, new Dummy(50, 0));

            p.Enemy = m;
            m.Enemy = p;

            player = p;
            enemy = m;

            player.OnDeath += () => OnEndGame(1);
            enemy.OnDeath += () => OnEndGame(0);

            player.Setup();
            enemy.Setup();

            Array.Fill(eleminates, 0);

            player.RuneCtrl.OnRuneElim += ele =>
            {
                eleminates[ele.AsInt()] += 1;
            };

            base.OnLoad(msg);

            View.BindCombat(this);

            View.CastUltraTriggered += player.ultra.Cast;
            View.PauseTriggered += PauseCombat;
            View.CloseTriggered += Os.PopContext;
            View.ToggleAutoUltra += () =>
            {
                player.UltraAuto = !player.UltraAuto;
                View.SetAutoUltra(player.UltraAuto);
            };

            _pauseDialog = new DialogBuilder()
                .WithTitle("COMBAT PAUSED")
                .AddButton("Save & Quit", () => { })
                .AddButton("Restart Game", () =>
                {
                    Os.HideAlert();
                    var ctx = new CombatContext
                    {
                        OnCombatEnd = OnCombatEnd
                    };
                    Os.ReplaceContext(ctx, Msg.Single("runes", player.RuneCtrl.RuneNames.ToArray()));
                })
                .AddCloseButton(Os)
                .Build();

        }

        public override void OnTick()
        {
            if (_isEnd || _pause) return;

            player.Tick();
            enemy.Tick();
        }

        private void OnEndGame(int winnerIndex)
        {
            if (_isEnd) return;

            View.ShowWinning(winnerIndex);
            OnCombatEnd?.Invoke(CombatEndStats.Create(winnerIndex, eleminates));

            _isEnd = true;
        }

        private void PauseCombat()
        {
            _pause = true;
            Os.ShowAlert(_pauseDialog);
        }
    }
}